package xyz.chaobei.mall.config;

import com.alibaba.fastjson.JSON;
import org.aopalliance.intercept.Joinpoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

/**
 * @author <a href='mailto:maruichao52@gmail.com'>MRC</a>
 * @since 2021/3/3
 */
@Aspect
@Component
public class WebLogAspect {

    private final Logger logger = LoggerFactory.getLogger(WebLogAspect.class);

    /**
     * <p>controller 层日志切点
     * <p>author: <a href='mailto:maruichao52@gmail.com'>MRC</a>
     * @since 2021/3/3
     * @return void
     **/
    @Pointcut("execution(public * xyz.chaobei.mall.controller.*.*(..))")
    public void controllerLog() {
    }

    /**
     * <p>service 层日志切点
     * <p>author: <a href='mailto:maruichao52@gmail.com'>MRC</a>
     * @since 2021/3/3
     * @return void
     **/
    @Pointcut("execution(public * xyz.chaobei.mall.service.*.*(..))")
    public void serviceLog() {
    }


    @Before("controllerLog()")
    public void beforeAdvice() {

        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();

        logger.info("system before url={}", request.getRequestURL());
        logger.info("system before uri={}", request.getRequestURI());

        logger.info("system before ip={}", request.getRemoteAddr());
        logger.info("system before method={}", request.getMethod());
    }

    @Around("controllerLog()")
    public Object controllerAround(ProceedingJoinPoint point) throws Throwable {

        logger.info("controllerAround args={}", JSON.toJSONString(point.getArgs()));
        Object result = point.proceed();
        logger.info("controllerAround result={}", JSON.toJSONString(result));

        return result;
    }

    @Around("serviceLog()")
    public Object serviceAround(ProceedingJoinPoint point) throws Throwable {

        logger.info("serviceAround args={}", JSON.toJSONString(point.getArgs()));
        Object result = point.proceed();
        logger.info("serviceAround result={}", JSON.toJSONString(result));

        return result;
    }

}
